package name.fuhan.view;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.LinearGradient;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Shader;
import android.os.Build;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.view.View;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;


/**
 * Created by fuhan on 2017/4/27.
 */

public class LineChartView extends View {
    private final Paint paint;
    private final int dp10;
    private final int dp6;
    private final int dp40;
    private final int dp20;
    private final int dp1;
    private final int dp05;
    private int height;
    private int width;
    ArrayList<Integer> data = new ArrayList();
    int max;
    private Date lastTime;

    {//TEST
        for (int i = 0; i < 7; i++) {
            int i1 = (int) (Math.random() * 11);
            max = Math.max(max, i1);
            data.add(i1);
        }
    }

    /**
     * 数据应当以时间顺序排序
     * @param list 数据
     * @param lastTime 最后一天的日期
     */
    public void setData(ArrayList<Integer> list, Date lastTime) {
        data.clear();
        if (list != null) {
            data.addAll(list);
        }
        max = 0;
        for (Integer integer : data) {
            max = Math.max(max, integer);
        }
        this.lastTime = lastTime;
        postInvalidate();
    }

    public LineChartView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        paint = new Paint();
        paint.setAntiAlias(true);
        paint.setFilterBitmap(true);
        paint.setStyle(Paint.Style.STROKE);
        dp1 = dip2px(context, 1);
        dp05 = dp1 / 2;
        dp10 = dip2px(context, 10);
        dp6 = dip2px(context, 6);
        dp40 = dip2px(context, 40);
        dp20 = dip2px(context, 20);
        paint.setTextSize(dp10);
        Calendar calendar = Calendar.getInstance();
        lastTime = calendar.getTime();
    }


    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        height = getMeasuredHeight();
        width = getMeasuredWidth();
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        //底色
        paint.setStyle(Paint.Style.FILL);
        paint.setShader(new LinearGradient(0, height / 3, width, height * 2 / 3, 0xFF58B988, 0xFF46969F, Shader.TileMode.CLAMP));

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            canvas.drawRoundRect(0, 0, width, height, dp6, dp6, paint);
        } else {
            canvas.drawRect(0, 0, width, height, paint);
        }

        paint.setShader(null);
        paint.setColor(Color.WHITE);

        //边界计算
        Paint.FontMetrics fm1 = paint.getFontMetrics();
        float leftTextWhite = paint.measureText(max + "") + dp10;
        Paint.FontMetrics fm = paint.getFontMetrics();
        float textHeight = fm.descent - fm.ascent;

        float startX = leftTextWhite;//图表左侧边界
        float endX = width - dp20;//右边界
        float startY = dp20;//上边界
        float endY = height - textHeight - dp10;

        int unit;
        if (max % 10 == 0) {
            unit = max / 10;
        } else {
            unit = max / 9;
        }

        int lineUnit = 1;//划线单位
        while (unit > lineUnit) {
            int i = unit % lineUnit;
            if (i > lineUnit / 2) {
                unit += lineUnit - i;
            } else {
                unit -= i;
            }
            lineUnit *= 10;
        }
        int lineCount;//划线数量
        if (max % lineUnit == 0) {
            lineCount = max / lineUnit;
        } else {
            lineCount = max / lineUnit + 1;
        }
        if (lineCount < 5)
            lineCount = 5;

        //横线
        paint.setStrokeWidth(dp1);
        canvas.drawLine(startX, endY, endX + dp20 / 2, endY, paint);//0线
        paint.setStrokeWidth(dp05 / 2);
        float tubiaoHeigh = endY - startY;
        for (int i = 0; i < lineCount + 1; i++) {
            float lineH = (tubiaoHeigh / lineCount) * i;
            canvas.drawLine(startX, endY - lineH, endX, endY - lineH, paint);
            String text = i * lineUnit + "";
            float textW = paint.measureText(text);
            canvas.drawText(text, startX / 2 - textW / 2, endY - lineH - fm1.bottom + (fm1.bottom - fm1.top) / 2, paint);//左字
        }

        //竖线
        paint.setStrokeWidth(dp1);
        canvas.drawLine(startX, startY - dp20 / 2, startX, endY, paint);//0线
        int vLineCount = data.size();//竖线数量
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(lastTime);
        calendar.add(Calendar.DAY_OF_YEAR, -vLineCount + 1);//第一天
        float vLineUnit = (endX - startX) / (vLineCount - 1);

        Path path = new Path();
        path.moveTo(startX, endY);
        float lastX = 0;
        VLineSpan vLineSpan;//竖线跨度
        if (data.size() < 15) {//半月内一天一写
            vLineSpan = VLineSpan.ONE_DAY;
        } else if (data.size() < 63) {//俩月内5天一写
            vLineSpan = VLineSpan.FIVE_DAY;
        } else if (data.size() < 367) {//一年内一月一写
            vLineSpan = VLineSpan.MONTH;
        } else {
            vLineSpan = VLineSpan.YEAR;
        }
        float lastTextRight = 0;
        for (int i = 0; i < vLineCount; i++) {
            float y = data.get(i) * (tubiaoHeigh / lineCount) / lineUnit;
            if (y == 0)
                y = 0.01f;
            y = endY - y;
            float x = startX + (i) * vLineUnit;
            lastX = x;
            path.lineTo(x, y);
            canvas.drawCircle(x, y, dp1, paint);
//            canvas.drawText(data.get(i) + "", x, y, paint);//TEST

            String timeStr;
            int dayOfMonth = calendar.get(Calendar.DAY_OF_MONTH);
            int dayOfYear = calendar.get(Calendar.DAY_OF_YEAR);
            if (dayOfYear == 1) {//如果是当年第一天,应写年份
                DateFormat dateFormat2 = new SimpleDateFormat("yyyy年");
                timeStr = dateFormat2.format(calendar.getTime());
            } else if (dayOfMonth == 1 || i == 0) {//如果是当月第一天,应写月份
                if (i == 0) {
                    Calendar calendar1 = Calendar.getInstance();
                    if (calendar.get(Calendar.YEAR) != calendar1.get(Calendar.YEAR)) {//如果不是今年
                        DateFormat dateFormat2 = new SimpleDateFormat("yyyy年MM月dd");
                        timeStr = dateFormat2.format(calendar.getTime());
                    } else {
                        DateFormat dateFormat2 = new SimpleDateFormat("MM月dd");
                        timeStr = dateFormat2.format(calendar.getTime());
                    }
                } else {
                    DateFormat dateFormat2 = new SimpleDateFormat("MM月");
                    timeStr = dateFormat2.format(calendar.getTime());
                }
            } else {
                DateFormat dateFormat2 = new SimpleDateFormat("dd");
                timeStr = dateFormat2.format(calendar.getTime());
            }

            boolean draw = false;
            switch (vLineSpan) {
                case ONE_DAY:
                    draw = true;//每天写
                    break;
                case FIVE_DAY:
                    if (dayOfMonth == 1 || dayOfMonth % 5 == 0) {//一号或5的倍数号
                        draw = true;
                    }
                    break;
                case MONTH:
                    if (dayOfMonth == 1) {//每月一写
                        draw = true;
                    }
                    break;
                case YEAR:
                    if (dayOfYear == 1) {//每年一写
                        draw = true;
                    }
                    break;
            }
            if (i == 0)//第一天要写
                draw = true;

            if (draw) {
                canvas.drawLine(x, endY - dp10, x, endY, paint);
                float textW = paint.measureText(timeStr);
                float textX = x - textW / 2;
                if (textX < 0) {
                    textX = 0;
                }
                if (textX < lastTextRight) {
                    textX = lastTextRight;
                }
                canvas.drawText(timeStr, textX, endY + (height - endY) / 2 - fm1.bottom + (fm1.bottom - fm1.top) / 2, paint);
                lastTextRight = textX + textW + paint.measureText(" ");
            }

            calendar.add(Calendar.DAY_OF_YEAR, 1);

        }
        paint.setStrokeWidth(dp05);
        paint.setStyle(Paint.Style.STROKE);
        canvas.drawPath(path, paint);
        path.lineTo(lastX, endY);
        path.close();
        paint.setAlpha(40);
        paint.setStyle(Paint.Style.FILL);
        canvas.drawPath(path, paint);
        paint.setAlpha(255);

    }

    private enum VLineSpan {
        ONE_DAY, FIVE_DAY, MONTH, YEAR
    }

	/**
     * 根据手机的分辨率从 dp 的单位 转成为 px(像素)
     */
    public static int dip2px(Context context, float dpValue) {
        final float scale = context.getResources().getDisplayMetrics().density;
        return (int) (dpValue * scale + 0.5f);
    }
}
